function PicBoard(){
	this.version = "0.6";
	this.language = "";
	this.availableLanguages = {};
	this.baseURL = "";
	this.tableTemplate = '<table id="propTable" border="0" width="100%">{tContent}</table>';
	this.cellTemplate = '<tr><td width="100px">{prop}</td><td>{val}</td></tr>';
	this.fontTemplate = "";
	this.fontOptions = "";
	this.languageMap = {};
	this.institutions = {};
	this.managedGroups = {};
	this.messages = {};
	this.regex = {
		extension: /\.(\w+)(?:\?\d+)?$/
	}
	
	this.onLoadEvents = new Array();
	this.onInitEvents = new Array();
	
	this.addLoadEvent = function(f){
		PicBoard.onLoadEvents.push(f);
	}

	this.addInitEvent = function(f){
		PicBoard.onInitEvents.push(f);
	}
	
	this.getTranslations = function(terms, callback){
		var sendData = { "terms" : terms, "l" : PicBoard.language };
	
		$.ajax({
			type: "POST",
			url: PicBoard.baseURL + "rsrc.php?req=getTranslations",
			data: sendData,
			dataType: 'json',
			success: function(msg){
				PicBoard.languageMap = $.extend(PicBoard.languageMap, msg.payload);
				callback(msg);
			}
		});
		
		delete sendData;
	}
	
	this.changeLanguage = function(){
		//console.dir(PicBoard.availableLanguages);
		
		var content = $('<div />', { id: 'langDialogHolder' })
						.append( $("<h3>", { text: this.languageMap.lang_197_selectLanguage }) );
		
		$.each(PicBoard.availableLanguages, function(i, v){
			var newURL = window.location.toString().replace(PicBoard.language, i);
			
			$(content).append(
				$("<div>", { 'class': "buttonSeperator" }).append(
					$("<img />", { src: PicBoard.baseURL + 'images/flags/' + i + '.gif' } )
					.after($("<button>", { 
						text: v,
						click: function(){ window.location = newURL } 
					}))
				)
			);
		});
		
		jQuery.facebox(content);

		if($.browser.msie != true) $('button').button();
	}
	
	return true;
}



function chart(){
	this.properties = 	{ 	'title' : {'displayText': 'lang_13_selTitle', 'dataType': 'string' },
							'description' : {'displayText' : 'lang_63_description', 'dataType': 'textarea' },
							'visibility' : {'displayText': 'lang_64_visibility', 'dataType': 'select', 'acceptedValues': 'visible,hidden' },
							'chartID' : { 'displayText': '', 'dataType': 'hidden' },
							'groupID' : { 'displayText': '', 'dataType': 'hidden' },
							'bookID' : { 'displayText': '', 'dataType': 'hidden' }
	};
	
	this.title = '';
	this.description = '';
	this.visibility = 'visible';
	this.chartID = 0;
	this.groupID = 0;
	this.bookID = 0;

	this.displayProperties = function(){
		// Create information in the properties pane for this cell.
		var output = '';
		for (var p in this.properties){
			
			if(this.properties[p].dataType == 'hidden') continue; // Don't show hidden properties.
			
			output += PicBoard.cellTemplate.replace("{prop}", this.properties[p].displayText);
			//this.properties[p] - allowed types
			
			if(this.properties[p].dataType == 'select'){
				var outputStr = "<select id='select" + p + "'>";
				var options = this.properties[p].acceptedValues.split(',');
				for(var o in options){
					if(options[o] == eval("this." + p)){
						outputStr += "<option value='" + options[o] + "' selected='selected'>" + options[o] + "</option>";
					} else {
						outputStr += "<option value='" + options[o] + "'>" + options[o] + "</option>";
					}
				}
				output = output.replace("{val}", outputStr + "</select>");
				
			}
			
			if(this.properties[p].dataType == 'string') output = output.replace("{val}", "<input type='text' name='txt" + p + "' id='txt" + p + "' value='" + eval("this." + p) + "' />");

			if(this.properties[p].dataType == 'textarea') output = output.replace("{val}", "<textarea id='txt" + p + "'>" + eval("this." + p) + "</textarea>");
			
			// Integer controls
			if(this.properties[p].dataType == 'int') {
				
				output = output.replace("{val}", $('<span>', { 'class': 'intAnchor ' + p, id: 'intAnchor' + Math.floor(Math.random()*100), text: eval("this." + p) }).outerHTML());
			}
			
			if(this.properties[p].dataType == 'colour') {
				output = output.replace("{val}", $('<span>', { 'class': 'colourAnchor ' + p, 'id': 'colourAnchor' + Math.floor(Math.random()*100), 'text': eval("this." + p) }).append($('<img>', { src: PicBoard.baseURL + 'images/palette.png', border:0 })).get()[0].outerHTML );
			}
			
			if(this.properties[p].dataType == 'fontDropdown'){
				// Font dropdown
				output = output.replace("{val}", PicBoard.fontTemplate);
			}
			
			if(this.properties[p].dataType == 'fontOptions'){
				output = output.replace("{val}", PicBoard.fontOptions);
			}
			
			// Immutable data
			if(this.properties[p].dataType == 'immutable') output = output.replace("{val}", eval("this." + p) );
		}
		outputString = PicBoard.tableTemplate.replace("{tContent}", output) + "<input type='button' id='PBpropApply' value='Apply'>";

		return outputString;
	}
	
	// Function used for saving data. Pulls information out of the object in JSON form so that we can send it to the server.
	this.returnProperties = function(){
		output = { };
		
		for (var p in this.properties){
			eval("output." + p + " = " + "this." + p);
		}
		return output;
	}
}



function cell(){
	this.properties = { 'text': {'displayText': 'lang_5_selText', 'dataType': 'string'}, 
						'textLocation': {'displayText': 'lang_6_selTextLocation', 'dataType': 'choice', 'acceptedValues': 'top,bottom', 'images': { 'top': 'images/edit-vertical-alignment-top.png', 'bottom': 'images/edit-vertical-alignment.png' } },
						'textAlignment' : {'displayText' : 'lang_27_selTextAlign', 'dataType': 'choice', 'acceptedValues': 'left,center,right', 'images': { 'left':'images/edit-alignment.png', 'center':'images/edit-alignment-center.png', 'right':'images/edit-alignment-right.png' } },
						'textSize' : { 'displayText' : 'lang_28_selTextSize', 'dataType' : 'int', 'stepping': 1, 'max': 30, 'min': 8 },
						'textOptions' : {'displayText' : 'lang_47_fontOptions', 'dataType' : 'fontOptions'},
						'fontFace' : { 'displayText': 'lang_46_font', 'dataType' : 'fontDropdown'},
						'colour': {'displayText': 'lang_7_selTextColour', 'dataType': 'colour'},
						'image': {'displayText': 'lang_8_selImage', 'dataType': 'hidden'},
						'bgcolour': {'displayText': 'lang_9_selBackgroundColour', 'dataType': 'colour'},			
						'textHeight': {'displayText': 'lang_10_selTextHeight', 'dataType': 'int', 'stepping': 4, 'max':120, 'min': 15 },
						'frameColour': {'displayText': 'lang_29_cellFrameColour', 'dataType': 'colour'},
						'gridRef[0]': {'displayText': 'lang_11_selCell', 'dataType': 'hidden'},
						'gridRef[1]': {'displayText': 'lang_12_selColumn', 'dataType': 'hidden'},
						'source' : { 'displayText' : '', 'dataType': 'hidden' },
						'PBCbold' : { 'displayText' : '', 'dataType': 'hidden' },
						'PBCitalic' : { 'displayText': '', 'dataType': 'hidden' },
						'PBCunderline' : { 'displayText': '', 'dataType': 'hidden' },
						'imageID' : { 'displayText': '', 'dataType': 'hidden' }
						};
	this.image = ''; // Image src
	this.gridRef = ['', '']; // location in grid.
	this.text = '';
	this.bgcolour = 'white';
	this.fontFace = 'Verdana, Geneva, sans-serif';
	this.colour = 'black';
	this.frameColour = 'black';
	this.textLocation = 'top';
	this.textAlignment = 'center';
	this.textHeight = 27;
	this.textSize = 16;
	this.PBCbold = false;
	this.PBCitalic = false;
	this.PBCunderline = false;
	this.source = 'mulberry';
	this.imageID = 0;
	
	this.displayProperties = function(){
		// Create information in the properties pane for this cell.

		var output = '';
		for (var p in this.properties){
			
			if(this.properties[p].dataType == 'hidden') continue; // Don't show hidden properties.
			
			if(this.properties[p].dataType == 'string') this.properties[p].displayText = "<label for='txt"+p+"'>"+this.properties[p].displayText+"</label>";
			if(this.properties[p].dataType == 'fontDropdown') this.properties[p].displayText = "<label for='PBCellfontPicker'>"+this.properties[p].displayText+"</label>";
			output += PicBoard.cellTemplate.replace("{prop}", this.properties[p].displayText);
			//this.properties[p] - allowed types

			if(this.properties[p].dataType == 'choice'){
				var outputStr = "<div class='radioset'>";
				var options = this.properties[p].acceptedValues.split(',');

				i = 0;

				for(var o in options){
					if(options[o] == eval("this." + p)){
						outputStr += "<input type=\"radio\" value=\"" + options[o] + "\" id=\"radio_" + p + i + "\" name=\"radio_" + p + "\" checked=\"checked\" /><label for=\"radio_" + p + i + "\"><img src='" + PicBoard.baseURL + this.properties[p].images[options[o]] + "' /></label>";
					} else {
						outputStr += "<input type=\"radio\" value=\"" + options[o] + "\" id=\"radio_" + p + i + "\" name=\"radio_" + p + "\" /><label for=\"radio_" + p + i + "\"><img src='" + PicBoard.baseURL + this.properties[p].images[options[o]] + "' /></label>";
					}
					i++;
				}
				
				output = output.replace("{val}", outputStr + "</div>");
				
			}
						
			
			if(this.properties[p].dataType == 'select'){
				var outputStr = "<select id='select" + p + "'>";
				var options = this.properties[p].acceptedValues.split(',');
				for(var o in options){
					if(options[o] == eval("this." + p)){
						outputStr += "<option value='" + options[o] + "' selected='selected'>" + options[o] + "</option>";
					} else {
						outputStr += "<option value='" + options[o] + "'>" + options[o] + "</option>";
					}
				}
				output = output.replace("{val}", outputStr + "</select>");
				
			}
			
			if(this.properties[p].dataType == 'string') output = output.replace("{val}", "<input type='text' name='txt" + p + "' id='txt" + p + "' value='" + eval("this." + p) + "' />");
			
			// Integer controls
			if(this.properties[p].dataType == 'int') {
				output = output.replace("{val}", $('<span>', { 'class': 'intAnchor ' + p, id: 'intAnchor' + Math.floor(Math.random()*100), text: eval("this." + p) }).outerHTML());
			}
			
			if(this.properties[p].dataType == 'colour') {
				output = output.replace("{val}", $('<span>', { 'class': 'colourAnchor ' + p, 'id': 'colourAnchor' + Math.floor(Math.random()*100), 'text': eval("this." + p) }).append($('<img>', { src: PicBoard.baseURL + 'images/palette.png', border:0 })).outerHTML() );
			}
			
			if(this.properties[p].dataType == 'fontDropdown'){
				// Font dropdown
				output = output.replace("{val}", PicBoard.fontTemplate);
			}
			
			if(this.properties[p].dataType == 'fontOptions'){
				output = output.replace("{val}", PicBoard.fontOptions);
			}
			
			// Immutable data
			if(this.properties[p].dataType == 'immutable') output = output.replace("{val}", eval("this." + p) );
		}
		outputString = PicBoard.tableTemplate.replace("{tContent}", output);

		return outputString;
	}
	
	// Function used for saving data. Pulls information out of the object in JSON form so that we can send it to the server.
	this.returnProperties = function(){
		output = { gridRef : this.gridRef };
		
		for (var p in this.properties){
			eval("output." + p + " = " + "this." + p);
		}
		return output;
	}
}



// Create an instance of the PicBoard object.
var PicBoard = new PicBoard();
PicBoard.constructor.prototype.cellObj = new cell();
PicBoard.constructor.prototype.chartObj = new chart();

function loadResources(){
	langTranslate = ['lang_1_chartName', 'lang_197_selectLanguage', 'lang_51_yes', 'lang_52_no'];
	for(i in PicBoard.cellObj.properties){
		langTranslate.push(PicBoard.cellObj.properties[i].displayText);
	}
	
	for(i in PicBoard.chartObj.properties){
		langTranslate.push(PicBoard.chartObj.properties[i].displayText);
	}	
	
	PicBoard.getTranslations(langTranslate, translatePage);
	
	// Get the list of enrolled institutions
	$.ajax({ type: "GET", url: PicBoard.baseURL + "rsrc.php?req=getInitInfo", dataType: 'json', success: 
		function(msg){
			if(msg != null){
				PicBoard.institutions = msg.institutions;
				PicBoard.managedGroups = msg.groups; 
				PicBoard.availableLanguages = msg.languages;
				PicBoard.messages = msg.messages;
			
			
				for(i in PicBoard.onInitEvents){
					eval(PicBoard.onInitEvents[i]);
				}
			}
		} 
	});
}

function translatePage(data){
	// Update the cell text & chart text to reflect language alterations.
	for(i in PicBoard.cellObj.properties){
		PicBoard.cellObj.properties[i].displayText = PicBoard.languageMap[PicBoard.cellObj.properties[i].displayText];
	}
	
	for(i in PicBoard.chartObj.properties){
		PicBoard.chartObj.properties[i].displayText = PicBoard.languageMap[PicBoard.chartObj.properties[i].displayText];
	}
}

function setUpLinks(){
	$('#PBgoToHome').bind('click', function(){
		window.location = PicBoard.baseURL + PicBoard.language + "/home";
	});

	$('#controlBar > a[id][title]').tipsy({gravity: 's'});
}

function getFragment(fragment, callback){
	// Used for fetching xhrfragments from the server. Callback should accept one argument, which contains the HTML returned by the call.
	$.ajax({
		url: PicBoard.baseURL + 'rsrc.php?req=getFragment&f=' + fragment,
		success: function(data) { 
			callback(data); 
			// IE sucks
			if($.browser.msie != true) $('button').button();
		}
	});
}

function showMessagePane(message, callback, options){
	$("#messagePane").html(message);
	
	if(options != null){
		if(options.yesnoButtons == true){
			$("#messagePane").append( $("<br>") );
			$("#messagePane").append( $("<button>", { 'text': PicBoard.languageMap.lang_51_yes, 'click': options.yesAction }) );
			$("#messagePane").append( $("<button>", { 'text': PicBoard.languageMap.lang_52_no, 'click': options.noAction }) );
		}
	}
	$('#messagePane').show("blind", null, 500, callback);
}

function browserDependentImage(src){
	if(src == "") return;
	
	var imgTmp = src.match(PicBoard.regex.extension);
	
	// Webkit doesn't seem to address SVG's properly. If a SVG has the same URL as another they will both be manipulated with PicBoard.
	// For the time being this fix seems to work. It's fairly hacky, but until WebKit fix it at their end there isnt much we can do.
	if(/svg$/i.test(src) && $.browser.webkit) src += "?" + randID();
	
	// non straight street URL's.
	if(/straight-street/i.test(src) == false) {
		if(/svg$/i.test(imgTmp[0])){
			// Proxy local images also. We need to remove any SVG markup thats going to define specific sizes (will muck up resizing)
			return SVGProxy(src);
		}
		return src;
	}
	
	if(typeof imgTmp != "undefined" && imgTmp != null) {
		if(imgTmp.length > 0){
			// If this is IE we're going to have to change to WMF.
			if($.browser.msie){
				return src.replace(/svg/ig, "wmf");	
			} else {
				// Load the SVG
				svgURL = src.replace(/wmf/ig, "svg");	

				return SVGProxy(svgURL);
			}
			
			return false;
		}
	}
	return false;
}

function randID(){
	return Math.floor(Math.random() * 10000);
}

function SVGProxy(url){
	var m = url.match(/http:\/\/(.*?)$/);
	return PicBoard.baseURL + "SVGProxy.php?r=" + m[1];
}

function browserDependentTag(src){
	var ext = src.match(PicBoard.regex.extension);
	
	if(typeof ext != "undefined" && ext != null) {
		if(ext.length > 0){
			if($.browser.msie){
				return $("<img>");	
			} else {
				if(/svg$/i.test(ext) == false){
					return $("<img>");
				}
				
				if(jQuery.browser.webkit){
					return $("<img>");
				} else {
					return $("<embed type='image/svg+xml'>");
				}
			}
		}
	}
	return;
}

function ato(a){
	var o = {};
	for(var i=0;i<a.length;i++){
		o[a[i]]='';
	}
	return o;
}

$(document).ready(function(){
	if (typeof console == "undefined" && $.browser.msie) var console = { log: function() {}, dir: function(){} }; 
	
	loadResources();
	// Run queued loading commands.
	for(i in PicBoard.onLoadEvents){
		eval(PicBoard.onLoadEvents[i]);
	}
	
	$('div.button').hover(
		function() { $(this).addClass('ui-state-hover'); }, 
		function() { $(this).removeClass('ui-state-hover'); }
	);
	
	$('button, .aristo-button').button();
	
	$('.iconHelper').tipsy();
	
	if($.browser.msie && parseInt(jQuery.browser.version) == 6) alert('This browser is unsupported. Please upgrade to a modern browser.');
	
	jQuery.fn.outerHTML = function(s) {
		return (s) 
		? this.before(s).remove()
		: jQuery("<p>").append(this.eq(0).clone()).html();
	}
	
	setUpLinks();
	
});